-module(data).
-include("define.hrl").
-export([start/0, stop/0]).

-export([
    get_row/2, 
    get_value_by_key/2, 
    get_row_multi_value/3, 
    get_multi_value/2, 
    get_value/2, 
    get_all_values/1, 
    get_low_key/2, 
    get_all_keys/1, 
    get_row_value/3
]).

start()->
    case application:start(data_app) of
        ok -> ok;
        {error, {already_started, data_app}} -> ok
    end.

stop() ->
    application:stop(data_app),
    erlang:halt().

get_data_base(DataName) ->
    case ets:lookup(?DATA_TABLE_INFO, utl:to_binary(DataName)) of
        []-> 
            {error, undefined};
        [Object]-> 
            Object#dataTableInfo.tableID
    end.

get_all_keys(DataName) ->
    case ets:lookup(?DATA_TABLE_INFO, utl:to_binary(DataName)) of
        []-> 
            {error, undefined};
        [Object]-> 
            Object#dataTableInfo.keys
    end.

get_row(DataName, Key) ->
    get_value_by_key(DataName, Key).

get_value_by_key(DataName, Key) ->
    TableID = get_data_base(DataName),
    case ets:lookup(TableID, utl:to_binary(Key)) of
        [] -> {error, undefined} ;
        [DataKeyValue] -> {ok, DataKeyValue#dataKeyValue.value}
    end.

get_row_multi_value(DataName, Key, FieldList) ->
    case get_row(DataName, Key) of
        {error, undefined} -> undefined;
        {ok, Row} ->
            get_multi_value(Row, FieldList)
    end.

get_multi_value(Row, FieldList) ->
    lists:map(fun(Field) -> get_value(Row, Field) end, FieldList).

get_value(Row, Field)->
    proplists:get_value(utl:to_binary(Field), Row).

get_all_values(DataName) ->
    Keys = get_all_keys(utl:to_binary(DataName)),
    [Row || {ok, Row} <- [get_row(DataName, Key)||Key <- Keys]].

get_low_key(DataName, Key) ->
    AllKeys = get_all_keys(DataName),
    [First|_] = AllKeys,
    get_low_key(Key, First, AllKeys).

get_low_key(_Key, LastKey, []) -> LastKey;
get_low_key(Key, LastKey, [K|T]) -> 
    case Key >= utl:to_integer(K) of
        true -> get_low_key(Key, K, T);
        false -> LastKey
    end.

get_row_value(DataName, Key, Field) ->
    get_row_value(DataName, Key, Field, undefined).

get_row_value(DataName, Key, Field, Default) ->
    case get_row(DataName, Key) of
        {error, undefined} -> Default;
        {ok, Row} ->
            get_value(Row, Field)
    end.
